/*
 * @Copyright: Copyright (C) AMCAX, All rights reserved.
 * @Author: 殷建峰
 * @Date: 2025-01-20 12:56:21
 * @LastEditTime: 2025-02-12 18:13:32
 * @LastEditors: 殷建峰
 * @Description:
 */

import {
  BaseRenderer,
  DHElementEntity,
  EntityPartType,
  IEntity,
  LineEntity,
  ModelDataGeom,
  ModelDataMesh,
  NodesEntity,
  PointCloudEntity,
  RendererGeom,
} from '@amcax/web-render';

export class RendererShape extends BaseRenderer<ModelDataMesh | ModelDataGeom> {
  public render(modelData: (ModelDataMesh | ModelDataGeom)[]): IEntity[] {
    const entities: IEntity[] = [];
    for (const model of modelData) {
      if (model.category === 'CLOUD') {
        const cloud = model as ModelDataGeom;
        const points = this.createCloud(cloud);
        points && entities.push(points);
      } else if (model.category === 'MESH') {
        const mesh = model as ModelDataMesh;
        const nodes = this.createNodes(mesh);
        const dhElements = this.createDHElements(mesh);
        dhElements && entities.push(...dhElements);
        nodes && entities.push(nodes);
      } else if (model.category === 'CURVE') {
        const curve = model as ModelDataGeom;
        const line = this.createCurve(curve);
        line && entities.push(line);
      } else if (model.category === 'SHAPE') {
        const geom = model as ModelDataGeom;
        // 直接复用已有的RendererGeom，就不必重复实现了
        const rendererGeom = new RendererGeom();
        const geomEntities = rendererGeom.render([geom]);
        geomEntities && entities.push(...geomEntities);
      }
    }

    return entities;
  }

  private createCloud(modelData: ModelDataGeom): PointCloudEntity {
    if (!modelData.pointData) {
      return null;
    }
    const { position, normal } = modelData.pointData;
    return new PointCloudEntity(modelData.id, position, normal);
  }

  private createNodes(modelData: ModelDataMesh): NodesEntity {
    if (!modelData.nodeData) {
      return null;
    }
    const { position, ids } = modelData.nodeData;
    const points = new NodesEntity(modelData.id, ids, position);
    return points;
  }

  private createCurve(modelData: ModelDataGeom): LineEntity {
    if (!modelData.lineData) {
      return null;
    }
    const { position, ids, vertexStartIndices, renderType } =
      modelData.lineData;
    const lines = new LineEntity(
      modelData.id,
      ids,
      position,
      vertexStartIndices,
      renderType,
      { linewidth: 2, renderTypeColors: [0x1874cd] },
    );
    return lines;
  }

  private createDHElements(modelData: ModelDataMesh): DHElementEntity[] {
    const elements: DHElementEntity[] = [];
    const { id, d2Data, d3Data } = modelData;
    if (d2Data?.ids?.length > 0) {
      elements.push(
        new DHElementEntity(
          id,
          d2Data.ids,
          d2Data.position,
          d2Data.normal,
          d2Data.renderIndices,
          d2Data.vertexStartIndices,
          d2Data.wires,
          d2Data.wireStartIndices,
          EntityPartType.shellElement,
        ),
      );
    }
    if (d3Data?.ids?.length > 0) {
      elements.push(
        new DHElementEntity(
          id,
          d3Data.ids,
          d3Data.position,
          d3Data.normal,
          d3Data.renderIndices,
          d3Data.vertexStartIndices,
          d3Data.wires,
          d3Data.wireStartIndices,
          EntityPartType.solidElement,
        ),
      );
    }

    return elements;
  }
}
